package com.kinghood.infrastructure.util.base;

import com.kinghood.infrastructure.model.KingHoodExceptionUtil;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * description
 *
 * @author zhangFanJun
 * @date 2023-12-06 11:50
 **/
public class KingHoodUtil {

    public static void scanApi(int from, String path, String contextPath, String belong) {
        HashMap<String, Long> menuMap = new HashMap<>();
        menuMap.put("商品管理", 623168959053824L);
        menuMap.put("DownloadCenterController", 886552266850304L);
        menuMap.put("ProductBaseController", 835424196018176L);
        menuMap.put("BusinessLogController", 835424196018176L);

        menuMap.put("类目管理", 887363818536960L);
        menuMap.put("BaseGoodsController", 887773992108032L);
        menuMap.put("BaseCategoryController", 888388294066176L);

        menuMap.put("基础配置", 888566996582400L);
        menuMap.put("BaseAttributeController", 889425146986496L);
        menuMap.put("BaseAttributeGroupController", 889425146986496L);
        menuMap.put("经营配置", 888713205825536L);
        menuMap.put("BaseBrandController", 891604779974656L);
        menuMap.put("BaseLabelController", 890854460932096L);
        menuMap.put("BaseSupplierController", 891879888568320L);

        menuMap.put("系统管理", 893957407031296L);
        menuMap.put("OrganizationController", 894775053041664L);
        menuMap.put("MenuController", 894992779362304L);
        menuMap.put("RoleController", 894932096172032L);
        menuMap.put("SysDirectionCategoryController", 895064812339200L);
        menuMap.put("SystemDirectionController", 895064812339200L);
        menuMap.put("SysLogController", 895148211879936L);
        menuMap.put("ApiController", 895273697067008L);

        Reflections reflections = new Reflections(path, new SubTypesScanner(false), new TypeAnnotationsScanner());
        Set<Class<?>> controllerClasses = reflections.getTypesAnnotatedWith(RestController.class);
        controllerClasses.addAll(reflections.getTypesAnnotatedWith(Controller.class));

        ArrayList<String> list = new ArrayList<>();
        ArrayList<String> mList = new ArrayList<>();
        ArrayList<String> rList = new ArrayList<>();
        String add = "INSERT INTO `authority_api`(`id`, `api_name`, `url`, `sort`) VALUES ( {id}, '{name}','{url}',{sort});\n";
        String menu = "INSERT INTO `authority_menu`(`id`, `belong_type`, `resource_type`, `name`,`sort`) VALUES ({id},{belong},3,'{name}',{sort});\n";
        String relate = "INSERT INTO `authority_menu_api_relate`(`id`, `menu_id`, `api_id`) VALUES ({id},{menuId},{apiId});\n";
        int id = from;
        for (Class<?> controllerClass : controllerClasses) {
            RequestMapping classRequestMapping = controllerClass.getAnnotation(RequestMapping.class);
            String basePath = (classRequestMapping != null) ? classRequestMapping.value()[0] : "";

            Method[] methods = controllerClass.getDeclaredMethods();
            String name = controllerClass.getName();
            name = name.substring(name.lastIndexOf(".") + 1);
            for (Method method : methods) {
                String url = "";
                String urlName = name + "_" + method.getName();
                RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                if (requestMapping != null) {
                    String methodPath = requestMapping.value()[0];
                    url = basePath + methodPath;
                    System.out.println("API RequestMapping Endpoint: " + url);
                }
                GetMapping get = method.getAnnotation(GetMapping.class);
                if (get != null) {
//                    RequestMethod requestMethod = get.()[0];
//                    urlName = urlName + "_" + requestMethod.name();
                    String methodPath = get.value()[0];
                    url = basePath + methodPath;
                    System.out.println("API GetMapping Endpoint: " + url);
                }
                PostMapping post = method.getAnnotation(PostMapping.class);
                if (post != null) {
//                    RequestMethod requestMethod = post.()[0];
//                    urlName = urlName + "_" + requestMethod.name();
                    String methodPath = post.value()[0];
                    url = basePath + methodPath;
                    System.out.println("API PostMapping Endpoint: " + url);
                }
                // 处理请求存在restful风格的url
                String finalUrl = contextPath + url;
                if (url.contains("{")) {
                    finalUrl = url.substring(0, url.indexOf("{")) + "**";
                }

                String result = add.replace("{id}", String.valueOf(id))
                        .replace("{name}", urlName)
                        .replace("{url}", finalUrl)
                        .replace("{sort}", String.valueOf(id));
                list.add(result);

                String m = menu.replace("{id}", String.valueOf(id))
                        .replace("{belong}", belong)
                        .replace("{name}", urlName)
                        .replace("{sort}", String.valueOf(id));
                mList.add(m);

                String r = relate.replace("{id}", String.valueOf(id))
                        .replace("{menuId}", String.valueOf(id))
                        .replace("{apiId}", String.valueOf(id));
                rList.add(r);
                id++;
            }
        }
        for (String sql : list) {
            System.out.println(sql);
        }
        for (String sql : mList) {
            System.out.println(sql);
        }
        for (String sql : rList) {
            System.out.println(sql);
        }
    }

    /**
     * <p> 随机概率
     * <p> T是唯一标识，可以是表id或者参与抽取的名字等
     * <p> Integer是相对比例，
     * <p> 比如A,B,C比例是3:3:4，仅仅用B,C进行随机抽取，直接传递B3,C4即可
     *
     * @param in 入参
     * @return 返回唯一标识
     * @author zfj
     * @date 2023/7/7
     */
    public static Long randomChance(Map<Long, Integer> in) {
        KingHoodExceptionUtil.isEmpty(in, "入参不能为空");

        int min = in.values().stream().filter(Objects::nonNull).min(Integer::compareTo).orElse(0);
        int change = 50;
        if (min > 50) {
            change = 1;
        } else if (min > 0) {
            change = 50 / min + 1;
        }

        List<List<Long>> allList = new ArrayList<>();
        AtomicInteger num = new AtomicInteger(0);
        int finalChange = change;
        in.forEach((k, v) -> {
            int number = v * finalChange;
            num.addAndGet(number);
            ArrayList<Long> perList = new ArrayList<>(Collections.nCopies(number, k));
            allList.add(perList);
        });

        ThreadLocalRandom current = ThreadLocalRandom.current();
        ArrayList<Long> resultList = new ArrayList<>();
        for (int i = 0; i < num.get(); i++) {
            int k = current.nextInt(allList.size());
            List<Long> list = allList.get(k);
            int v = current.nextInt(list.size());
            resultList.add(list.remove(v));
            if (CollectionUtils.isEmpty(list)) {
                allList.remove(k);
            }
        }

        return resultList.get(current.nextInt(resultList.size()));
    }
}
